package PrjHttpUtils

import (
	"dgo/goutils/dnet"
	"dgo/goutils/utils"
	"gitee.com/ymofen/supervalue"
	"io/ioutil"
	"net/http"

	"fmt"

	"strings"
)

var (
	ResponseCodeMsg_Filter_Cb func(w http.ResponseWriter, code int, msg string) = nil
)

func GetRequestHeader(header map[string][]string, kvspliter, itmspliter string, bb *utils.BytesBuilder) {
	for k, v := range header {
		bb.Appendf("%s%s%s%s", k, kvspliter, v, itmspliter)
	}
}

func GetRequestHeaderAsString(header map[string][]string) string {
	var bb utils.BytesBuilder
	GetRequestHeader(header, ":", "\r\n", &bb)
	return bb.String()
}

func GetBodyAsString(r *http.Request) string {
	s, _ := ioutil.ReadAll(r.Body)
	return string(s)
}

func GetBodyAsJSON2(r *http.Request) *wrapper.SuperValue {
	s, _ := ioutil.ReadAll(r.Body)
	if len(s) > 0 {
		req, err := wrapper.NewValueFromJson(s, false, false)
		if err != nil {
			utils.Log.Warnf("JSON Parse err:%s", err.Error())
			return wrapper.NewSVObject()
		}
		return req
	} else {
		return wrapper.NewSVObject()
	}
}

func GetReqParamAsInt(r *http.Request, req *wrapper.SuperValue, key string, def int64) int64 {
	v := r.URL.Query().Get(key)

	if len(v) == 0 {
		v = r.FormValue(key)
	}

	if len(v) == 0 && req != nil {
		v = req.AsString(key, "")
	}

	if len(v) == 0 {
		return def
	}
	return utils.StrToInt64Def(v, def)
}

func GetReqParamAsString(r *http.Request, req *wrapper.SuperValue, key string, def string) string {
	v := r.URL.Query().Get(key)

	if len(v) == 0 {
		v = r.FormValue(key)
	}

	if len(v) == 0 && req != nil {
		v = req.AsString(key, "")
	}

	if len(v) == 0 {
		return def
	}
	return v
}

func GetQueryAsString(r *http.Request, key string, def string) string {
	v := r.URL.Query().Get(key)
	if len(v) == 0 {
		return def
	}
	return v
}

func GetQueryAsInt(r *http.Request, key string, def int) int {
	v := r.URL.Query().Get(key)
	if len(v) == 0 {
		return def
	}
	return utils.StrToIntDef(v, def)
}

func GetQueryAsFloat64(r *http.Request, key string, def float64) float64 {
	v := r.URL.Query().Get(key)
	if len(v) == 0 {
		return def
	}
	return utils.StrToFloat64Def(v, def)
}

func ResponseAsJSON(w http.ResponseWriter, resp string) {
	ResponseAsJSONBuf(w, []byte(resp))
}

func NetInfo2Json(netinfo *dnet.DNetInfo, titleJson, recJson *wrapper.SuperValue) {
	netinfo.GetInfoCb(func(k string, v interface{}) {
		if k == "recv_bytes" || k == "send_bytes" || k == "speed_sendbytes" || k == "speed_recvbytes" {
			recJson.SetKeyValue(k, utils.HumanFilesizeU(v.(uint64)))
		} else {
			recJson.SetKeyValue(k, v)
		}
	})

	if titleJson != nil {
		titleJson.SetKeyValues("online", "在线数",
			"max_online_cnt", "最大在线数",
			"dis_cnt", "断线次数", "con_cnt", "连接次数",
			"recv_bytes", "接收字节", "send_bytes", "发送字节",
			"speed_recvbytes", "接收字节(每秒)", "speed_sendbytes", "发送字节(每秒)",
			"recv_io", "接收IO(次)", "send_io", "发送IO(次)",
			"speed_recvio", "接收IO(次/s)", "speed_sendio", "发送IO(次/s)",
			"recvio", "接收IO", "sendio", "发送IO",
			"recvinfo", "接收信息", "sendinfo", "发送信息",
			"run-secs", "持续运行时间",
		)
	}
}

func ResponseAsJSONBuf(w http.ResponseWriter, resp []byte) {
	if w != nil {
		w.Header().Set("content-type", "application/json")
		w.Write(resp)
	}
}

func ResponseJSON2(w http.ResponseWriter, resp *wrapper.SuperValue) {
	if w != nil {
		w.Header().Set("content-type", "application/json")
		respBuf := resp.AsJSONBytes(true)
		w.Write(respBuf)
	}
}

func ResponseJSONValues(w http.ResponseWriter, kvParis ...interface{}) {
	if w != nil {
		w.Header().Set("content-type", "application/json")
		var jB utils.JSONBuilder
		jB.AddObject(kvParis...)
		w.Write(jB.Bytes())
	}

}

func SetRespCodeAndMsg(resp *wrapper.SuperValue, code int, msg string) {
	resp.SetKeyValue("code", code)
	if len(msg) > 0 {
		resp.SetKeyValue("msg", msg)
	}
}

func ResponseCodeAndMsg(w http.ResponseWriter, code int, msg string) {

	var str string
	if len(msg) > 0 {
		str = fmt.Sprintf("{\"code\":%d, \"msg\":\"%s\"}", code, utils.EscapeJsonStrSimple(msg))
	} else {
		str = fmt.Sprintf("{\"code\":%d}", code)
	}
	if w != nil {
		w.Header().Set("content-type", "application/json")
		w.Write([]byte(str))
	}

	if ResponseCodeMsg_Filter_Cb != nil {
		ResponseCodeMsg_Filter_Cb(w, code, msg)
	}

}

func AllowCrossAccessSet(w http.ResponseWriter) {
	if w != nil {
		w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Credential", "true")
	}
}

func GetHttpClientAddr(r *http.Request) string {
	xForwardedFor := r.Header.Get("X-Forwarded-For")
	ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
	if ip != "" {
		return ip
	}

	ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
	if ip != "" {
		return ip
	}

	return r.RemoteAddr
}

func GetHttpClientIp(r *http.Request) string {
	str := GetHttpClientAddr(r)
	if len(str) > 0 {
		strs := strings.SplitN(str, ":", 2)
		return strs[0]
	} else {
		return ""
	}

}
